#ifndef _TWOGRE_REAL_VARIABLE_H_
#define _TWOGRE_REAL_VARIABLE_H_

#include "TwOgrePrerequisites.h"
#include "TwOgreVariable.h"

#include "OgreString.h"



namespace TwOgre{

    class RealParams
    {
    public:
        RealParams(const Ogre::String& name)
            : parent_(0)
            , name_(name)
            , label_(Ogre::StringUtil::BLANK)
            , group_(Ogre::StringUtil::BLANK)
            , help_(Ogre::StringUtil::BLANK)
            , shortcutIncr_(Ogre::StringUtil::BLANK)
            , shortcutDecr_(Ogre::StringUtil::BLANK)
            , type_(TW_TYPE_DOUBLE)
            , readOnly_(false)
            , data_(NULL)
            , setCB_(NULL)
            , getCB_(NULL)
            , min_(0.0)
            , max_(REAL_INFINITY)
            , step_(1.00)
            , precision_(2)
            , value_(0.0)
        {}

        RealParams& label(const Ogre::String& varLabel)
        {
            label_ = varLabel;
            return *this;
        }
        RealParams& group(const Ogre::String& varGroup)
        {
            group_ = varGroup;
            return *this;
        }
        RealParams& help(const Ogre::String& varHelp)
        {
            help_ = varHelp;
            return *this;
        }
        RealParams& shortcut(const Ogre::String& increment, const Ogre::String& decrement)
        {
            shortcutIncr_ = increment;
            shortcutDecr_ = decrement;
            return *this;
        }
        RealParams& readOnly(bool varReadOnly)
        {
            readOnly_ = varReadOnly;
            return *this;
        }
        RealParams& callback(TwSetVarCallback setter, TwGetVarCallback getter, void* varData)
        {
            setCB_ = setter;
            getCB_ = getter;
            data_ = varData;
            return *this;
        }
        RealParams& limits(Ogre::Real min, Ogre::Real max=REAL_INFINITY, Ogre::Real step=REAL_INFINITY)
        {
            min_ = min;
            max_ = max;
            step_ = step;
            return *this;
        }
        RealParams& precision(const int digits)
        {
            precision_ = digits;
            return *this;
        }
        RealParams& value(const Ogre::Real& realVal)
        {
            value_ = realVal;
            return *this;
        }
    private:
        Window* parent_;
        Ogre::String name_;
        Ogre::String label_;
        Ogre::String group_;
        Ogre::String help_;
        Ogre::String shortcutIncr_;
        Ogre::String shortcutDecr_;
        TwType type_;
        bool readOnly_;
        void* data_;
        TwSetVarCallback setCB_;
        TwGetVarCallback getCB_;
        Ogre::Real min_;
        Ogre::Real max_;
        Ogre::Real step_;
        int precision_;

        Ogre::Real value_;

        friend class Window;
        friend class RealVariable;		
    };

    class TwOgreExport RealVariable : public Variable
    {
    protected:
        RealVariable(Window *parent, const Ogre::String& name, bool readOnly, const Ogre::String& label, 
            Ogre::Real value, const Ogre::String& groupName, const Ogre::String& help);
        RealVariable(RealParams& params);
        ~RealVariable();

    public:
        Ogre::Real getRealValue() const;
        void setRealValue(Ogre::Real value);

        void setPrecision(int precision);

        void setLimits(Ogre::Real min, Ogre::Real max=REAL_INFINITY, Ogre::Real step=REAL_INFINITY);
        void setShortcut(const Ogre::String& increment, const Ogre::String& decrement);

    private:
        mutable Ogre::Real mValue;
        double mDoubleValue;

        friend class Window;
    };
}; // End Namespace
#endif
